package com.solome.util.csv;

import java.io.IOException;
import java.io.Reader;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Comparator;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.ObjectMap;

public class CsvLoader<T> extends ObjectMap<Integer, T> {

	public Array<String[]> readCSVFile(String xlsFilePath) throws IOException {
		Array<String[]> sheet = new Array<String[]>(); // 用来保存数据
		FileHandle handle = Gdx.files.internal(xlsFilePath);
		Reader reader = handle.reader("GBK");

		CsvReader readerCsvReader = new CsvReader(reader);
		readerCsvReader.readHeaders(); // 跳过表头 如果需要表头的话，不要写这句。
		while (readerCsvReader.readRecord()) { // 逐行读入除表头的数据
			sheet.add(readerCsvReader.getValues());
		}
		reader.close();
		return sheet;
		// BufferedReader br = new BufferedReader(reader, reader.read());
		// String rec = null;// 一行
		// String str;// 一个单元格
		//
		// br.readLine();// 第一行为信息略过
		//
		// Array<Array<String>> sheet = new Array<Array<String>>();
		// try {
		// // 读取一行
		// while ((rec = br.readLine()) != null) {
		// Pattern pCells = Pattern
		// .compile("(\"[^\"]*(\"{2})*[^\"]*\")*[^,]*,");
		// Matcher mCells = pCells.matcher(rec + ",");
		// Array<String> cells = new Array<String>();// 每行记录一个list
		// // 读取每个单元格
		// while (mCells.find()) {
		// str = mCells.group();
		// str = str.replaceAll(
		// "(?sm)\"?([^\"]*(\"{2})*[^\"]*)\"?.*,", "$1");
		// str = str.replaceAll("(?sm)(\"(\"))", "$2");
		// cells.add(str);
		// }
		// sheet.add(cells);
		// }
		// } catch (Exception e) {
		// e.printStackTrace();
		// } finally {
		// if (reader != null) {
		// reader.close();
		// }
		// if (br != null) {
		// br.close();
		// }
		// }
		// return sheet;
	}

	/**
	 * 加载参数表
	 * 
	 * @param _class
	 */
	public Array<CsvParam> loadFields(Class<?> _class) {
		Array<CsvParam> params = new Array<CsvParam>();
		Field[] arrayOfField = _class.getDeclaredFields();
		for (Field field : arrayOfField) {
			if (field.getName().equals("serialVersionUID"))
				continue;
			Annotation[] anos = field.getDeclaredAnnotations();
			CsvParam param = new CsvParam();
			param.setField(field);
			for (Annotation annotation : anos) {
				if (annotation instanceof Num) {
					param.setNum(((Num) annotation).value());
				} else if (annotation instanceof XlsBoolean)
					param.setDataType(DataType.BOOLEAN);
				else if (annotation instanceof XlsByte)
					param.setDataType(DataType.BYTE);
				else if (annotation instanceof XlsShort)
					param.setDataType(DataType.SHORT);
				else if (annotation instanceof XlsInt)
					param.setDataType(DataType.INT);
				else if (annotation instanceof XlsDouble)
					param.setDataType(DataType.DOUBLE);
				else if (annotation instanceof XlsString)
					param.setDataType(DataType.STRING);
				else
					continue;
			}
			params.add(param);
		}
		params.sort(new Comparator<CsvParam>() {
			@Override
			public int compare(CsvParam o1, CsvParam o2) {
				// TODO Auto-generated method stub
				if (o1.getNum() - o2.getNum() > 0) {
					return 1;
				}
				if (o1.getNum() - o2.getNum() < 0) {
					return -1;
				}
				return 0;
			}
		});
		return params;
	}

	/**
	 * 加载单元数据
	 * 
	 * @param row
	 * @return
	 * @throws Exception
	 */
	private T loadUnit(String[] row, Array<CsvParam> params, Class<T> _class)
			throws Exception {
		// 创建工作对象实例
		Method method;// 工作方法
		T instance = _class.newInstance();
		for (int x = 0; x < params.size; ++x) {// 加载参数表
			CsvParam param = params.get(x);
			String cell = row[x];
			// 如果取项为空，跳出加载
			if (cell == null) {
				continue;
			}

			// 如果读到结束宏，跳出加载
			if (cell.toString().equalsIgnoreCase("end")) {
				return null;
			}

			// if (param.getField().getModifiers() == Member.DECLARED) {
			// try {
			// if (param.getDataType() == DataType.BOOLEAN) {
			// param.getField().setBoolean(instance,
			// CellUtils.getBoolean(cell));
			// break;
			// }
			// if (param.getDataType() == DataType.BYTE) {
			// param.getField().setByte(instance,
			// CellUtils.getByte(cell));
			// break;
			// }
			// if (param.getDataType() == DataType.INT) {
			// param.getField().setInt(instance,
			// CellUtils.getInt(cell));
			// break;
			// }
			// if (param.getDataType() == DataType.SHORT) {
			// param.getField().setShort(instance,
			// CellUtils.getShort(cell));
			// break;
			// }
			// if (param.getDataType() == DataType.DOUBLE) {
			// param.getField().setDouble(instance,
			// CellUtils.getDouble(cell));
			// break;
			// }
			// if (param.getDataType() == DataType.STRING) {
			// String value = CellUtils.getString(cell);
			// if (value == null) {
			// value = "";
			// }
			// param.getField().set(instance, value);
			// }
			// } catch (Exception ex) {
			// ex.printStackTrace();
			// System.err.println("出错字段：" + param.getField());
			// }
			// } else
			{
				method = null;
				try {
					String field = param.getField().getName();
					String tmp = field.substring(0, 1).toUpperCase();
					field = tmp + field.substring(1, field.length());
					String methodName = "set" + field;
					Object arg = null;
					if (param.getDataType() == DataType.STRING) {
						method = instance.getClass().getMethod(methodName,
								new Class[] { String.class });
						try {
							arg = CellUtils.getString(cell);
						} catch (Exception ex) {
							arg = Integer.valueOf(CellUtils.getInt(cell));
							System.err.println("出错字段：" + param.getField());
						}

					}
					if (param.getDataType() == DataType.BYTE) {
						method = instance.getClass().getMethod(methodName,
								new Class[] { Byte.TYPE });
						arg = Byte.valueOf(CellUtils.getByte(cell));
					} else if (param.getDataType() == DataType.SHORT) {
						method = instance.getClass().getMethod(methodName,
								new Class[] { Short.TYPE });
						arg = Short.valueOf(CellUtils.getShort(cell));
					} else if (param.getDataType() == DataType.INT) {
						method = instance.getClass().getMethod(methodName,
								new Class[] { Integer.TYPE });
						arg = Integer.valueOf(CellUtils.getInt(cell));
					} else if (param.getDataType() == DataType.BOOLEAN) {
						method = instance.getClass().getMethod(methodName,
								new Class[] { Boolean.TYPE });
						arg = Boolean.valueOf(CellUtils.getBoolean(cell));
					} else if (param.getDataType() == DataType.DOUBLE) {
						method = instance.getClass().getMethod(methodName,
								new Class[] { Double.TYPE });
						arg = Double.valueOf(CellUtils.getDouble(cell));
					}

					if (method == null) {
						throw new NullPointerException("方法[" + methodName
								+ "]不存在！");
					}

					method.invoke(instance, new Object[] { arg });
				} catch (Exception e) {
					e.printStackTrace();
					System.err.println("出错字段：" + param.getField());
				}
			}
		}
		return instance;
	}

	public ObjectMap<Integer, T> loadAll(Array<String[]> sheet,
			Array<CsvParam> params, Class<T> _class) throws Exception {
		// TODO Auto-generated method stub
		System.out.println(sheet.size);
		for (String[] row : sheet) {
			// 遭遇空行即跳出循环
			if (row == null) {
				break;
			}

			T instance = this.loadUnit(row, params, _class);
			// if (key.getField().getModifiers() == Member.DECLARED) {
			// Integer keyValue = Integer.valueOf(key.getField().getInt(
			// instance));
			// if (keyValue > 0) {
			// put(keyValue, instance);
			// }
			// } else
			{
				String keyValue = row[0];
				try {
					if (Integer.valueOf(keyValue) > 0) {
						put(Integer.valueOf(keyValue), instance);
					}
				} catch (Exception e) {
					// TODO: handle exception
					continue;
				}

				// String field = key.getField().getName();
				// String tmp = field.substring(0, 1).toUpperCase();
				// field = tmp + field.substring(1, field.length());
				// String methodName = "get" + field;
				// method = instance.getClass()
				// .getMethod(methodName, new Class[0]);
				// System.out.println("methodName=" + row[0]);
				// if (method == null) {
				// throw new NullPointerException("方法[" + methodName + "]不存在！");
				// }
				// Integer keyValue = (Integer) method.invoke(instance,
				// new Object[0]);
				// Logger.error(this, keyValue.toString());
				// if (keyValue > 0) {
				// put(keyValue, instance);
				// }
			}
		}
		return this;
	}
}
